<!DOCTYPE html>
<!--[if lt IE 7]> <html class="no-js ie6" lang="en"> <![endif]-->
<!--[if IE 7]>    <html class="no-js ie7" lang="en"> <![endif]-->
<!--[if IE 8]>    <html class="no-js ie8" lang="en"> <![endif]-->
<!--[if gt IE 8]><!-->  <html class="no-js" lang="en"> <!--<![endif]-->
<head>
	<meta charset="utf-8">
	<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
	
	<title>Decorator</title>
	
	<meta name="description" content="A jQuery library for modern HTML presentations">
	<meta name="author" content="Caleb Troughton">
	<meta name="viewport" content="width=1024, user-scalable=no">
	
	<!-- Core and extension CSS files -->
	<link rel="stylesheet" href="../core/deck.core.css">
	<link rel="stylesheet" href="../extensions/goto/deck.goto.css">
	<link rel="stylesheet" href="../extensions/menu/deck.menu.css">
	<link rel="stylesheet" href="../extensions/navigation/deck.navigation.css">
	<link rel="stylesheet" href="../extensions/status/deck.status.css">
	<link rel="stylesheet" href="../extensions/hash/deck.hash.css">
	<link rel="stylesheet" href="../extensions/scale/deck.scale.css">
	
	<!-- Style theme. More available in /themes/style/ or create your own. -->
	<link rel="stylesheet" href="../themes/style/swiss.css">
	
	<!-- Transition theme. More available in /themes/transition/ or create your own. -->
	<link rel="stylesheet" href="../themes/transition/horizontal-slide.css">
	
	<script src="../modernizr.custom.js"></script>
	

    <!-- SintaxHighlighter -->
	<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
	<title>SyntaxHighlighter Large File Demo</title>
	<script type="text/javascript" src="../SyntaxHighlighter-master/scripts/XRegExp.js"></script>
	<script type="text/javascript" src="../SyntaxHighlighter-master/scripts/shCore.js"></script>
	<script type="text/javascript" src="../SyntaxHighlighter-master/scripts/shBrushJava.js"></script>
	<script type="text/javascript" src="../SyntaxHighlighter-master/scripts/shBrushPlain.js"></script>
	<script type="text/javascript" src="../SyntaxHighlighter-master/scripts/shBrushPython.js"></script>
	<link type="text/css" rel="stylesheet" href="../SyntaxHighlighter-master/styles/shCoreEclipse.css"/>
	<!--link type="text/css" rel="stylesheet" href="../SyntaxHighlighter-master/styles/shThemeEclipse.css"/-->
	
	<script type="text/javascript">SyntaxHighlighter.all();</script>

	
	
</head>

<body class="deck-container">

<!-- Begin slides -->
<section class="slide" id="decorator1">
	<h2>Cafetería</h2>
	<p>Tenemos una cafetería que tiene una implementación inicial, y que esta creciendo rápidamente, agregando nuevos productos</p>

	<img src="firstDesign.png">
	<ul>
		<li>Beverage es una clase abstracta, heredada por todos los brebajes que se vendan en la cafetería.</li>
		<li>El método cost() es abstracto, las subclases necesitan crear su propia implementación, con el costo de cada brebaje</li>
		<li>Descripción es una variable de instancia que cada clase usa para guarda una descripción del producto.</li>
		<li>GetDescription() devuelve la descripción.</li>
	</ul>
</section>
<section class="slide" id="decorator2">
	<h2>Cafetería</h2>
	<p>Al los brebajes se le pueden agregar condimentos como leche, chocolate, leche y leche batida. La cafetería le carga el precio un poco por cada adicional, y tienen que reflejarlo en el precio final.</p>
	<img src="firstDesignAllClases.png">
	<p>Que pasa si el precio de la leche sube?</p>
	<p>Que pasa si se agrega un nuevo condimento</p>
	<p>Es obvio que este diseño no sirve, cada vez que quiero cambiar un precio de un adicional hay que cambiar todas las clases que lo usan</p>
</section>
<section class="slide" id="decorator3">
	<h2>Cafetería</h2>
	<h3>Otro diseño</h3>
	<p>Probamos con un diseño en el que representamos los condimentos y adicionales con variables de instancia.</p>
	<img src="secondDesign.png">
	<p>Variables de instancia booleanas para cada condimento para saber si tiene o no.</p>
	<p>Implementamos cost() en en en vez de dejarlo abstracto, las subclases van a sobreescribir cost() pero el cost() de la subclase va a usar el de la superclase, así pueden calcular el costo básico del brebaje de acuerdo a los adicionales en la supeclase y en la subclase sumarle el costo de los ingredientes agregados específicos.</p>
</section>
<section class="slide" id="decorator4">
	<h2>Cafetería</h2>
	<h3>Implementación supeclase Beverage</h3>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
	public abstract class Beverage {
		public String description;
		private boolean milk;
		private boolean soy;
		private boolean mocha;
		private boolean whip;
		
		private double milkCost  = 1.1;
		private double soyCost = 0.5;
		private double mochaCost = 1.3;
		private double whipCost = 0.9;
		
		public float cost(){
			float condimentCost = (float) 0.0;
			if (hasMilk()){
				condimentCost += milkCost;
			}
			if (hasMocha()){
				condimentCost += mochaCost;
			}
			if (hasSoy()){
				condimentCost += soyCost;
			}
			if (hasWhip()){
				condimentCost += whipCost;
			}
			return condimentCost;
		}
		public boolean hasMilk(){
			return milk;
		}
		public void setMilk(boolean has){
			this.milk = has;
		}
		public String getDescription() {
			return description;
		}
	}
	</script>
</section>
<section class="slide" id="decorator5">
	<h2>Cafetería</h2>
	<h3>Implementación de una de las subclases</h3>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
	public class DarkRoast extends Beverage{
		public DarkRoast(){
			description = "Most exelnt dark roast";
		}
		public float cost(){
			return (float) (1.99 + super.cost());
		}
	}
	</script>
	<h3>método main</h3>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
	public class StarbuzzCoffee {
		public static void main(String[] args) {
			Beverage beverage = new DarkRoast();
			
			System.out.println(beverage.getDescription() + " $" + beverage.cost());
			
			beverage.setMocha(true);
			beverage.setMilk(true);
			
			System.out.println(beverage.getDescription() + " $" + beverage.cost());
		}
	}
	</script>
</section>
<section class="slide" id="decorator6">
	<h2>Problemas de la implementación</h2>
	<p><strong>Qué requerimientos o factores pueden cambiar que puedan impactar en el diseño?</strong></p>
	<ul>
		<li>La implementación de hardcodear los valores en la superclase hace que haya que modificar el código cuando hay un cambio de precio.<BR/>
		Esto se podría haber solucionado haciendo variables de clase en ves de instancia y cargándolos en el programa cuando corre.</li>
		<li>Condimentos nuevos hacen que haya que cambiar el método cost() de la superclase.</li>
		<li>Todos los brebajes nuevos van a tener los métodos de todos los condimentos aunque no se posible por regla de negocio.</li>
		<li>Que pasa si uno quiere doble ración de condimento? (no podemos calcular el precio)</li>
	</ul>		
</section>
<section class="slide" id="decorator7">
	<h2>Problemas de la implementación</h2>
	<p><strong>Qué principios de diseño de los que vinos, no respetamos en esta implementación?</strong></p>
	<ol>
		<li>Identificar los aspectos de la aplicación que varían y separarlos de los que permanecen.</li>
		<li>Programar a interfaces, no a implementaciones</li>
		<li>Favorecer la composición sobre la herencia. "Tener un" puede ser mejor que "ser un".</li>
		<li>Esforzarse por diseños con acoplamiento débil entre los objetos que interactúan.</li>
	</ol>
</section>
<section class="slide" id="decorator8">
	<h2>Problemas de la implementación</h2>
	<p><strong>Qué principios de diseño de los que vinos, no respetamos en esta implementación?</strong></p>
	<ol>
		<li><strong>Identificar los aspectos de la aplicación que varían y separarlos de los que permanecen.</strong></li>
		<li>Programar a interfaces, no a implementaciones</li>
		<li><strong>Favorecer la composición sobre la herencia. "Tener un" puede ser mejor que "ser un".</strong></li>
		<li>Esforzarse por diseños con acoplamiento débil entre los objetos que interactúan.</li>
	</ol>
</section>
<section class="slide" id="decorator9">
	<h2>Repaso de conceptos</h2>
	<p>Como se hace entonces para tener re uso sin usar herencia?</p>
	<p>Hay maneras de hacer heredar comportamiento en tiempo de ejecución a través de la composición y delegación.</p>
	<p>Cuando se hereda comportamiento por medio de subclases ese comportamiento esta seteado en tiempo de compilado, y además todas las subclases heredan el mismo comportamiento, quedando como alternativa la sobreescritura de los métodos heredados como alternativa para cambiar el comportamiento heredado.</p>
	<p>Sin embargo si puedo extender el comportamiento de un objeto a través de composición, puedo adquirirlo o cambiarlo en tiempo de ejecución.</p>
</section>
<section class="slide" id="decorator10">
	<h2>Repaso de conceptos</h2>
	<p>Podemos agregar nuevas responsabilidades a los objetos a través de la composición, Inclusive se pueden agregar responsabilidades que no fueron pensadas por el diseñador de la superclase y sin tocar el código.<BR/>
	En el strategy a un pato se le asignaba una estrategia de vuelo o de quak en tiempo de ejecución.</p>
	<p>Usando composición se puede agregar de manera dinámica nuevas funcionalidades a los objetos escribiendo nuevo código, evitando cambiar el código ya existente, y con esto disminuyendo las chances de introducir bugs o causar efectos no deseados en el código.</p>
</section>
<section class="slide" id="decorator11">
	<h2>Principio de diseño</h2>
	<p>Las clases tiene que estar abiertas para la extensión pero cerradas para la modificación.</p>
	<p>El objetivo es extender clases incorporar nuevos comportamientos si modificar el código existente.</p>
	<p>Se logran diseños que son resistentes al cambio y flexibles para incorporar nuevas funcionalidades y alcanzar los requerimientos de cambio.</p>
	<p>Suena raro abierto para extender cerrado para modificar pero hay técnicas en la programación orientada a objetos que permiten extender funcionalidad sin cambiar el código, por ejemplo el Observer, agregando nuevos observers al Subject sin sin agregar ningún código. Decorator es un buen ejemplos de este principio.</p>
</section>
<section class="slide" id="decorator12">
	<h2>Principio de diseño</h2>
	<p>No se puede hacer que todo el código siga este principio.</p>
	<p>Hacer los diseños flexibles y abiertos lleva tiempo y esfuerzo además de agregarle nuevos niveles de abstracción y complejidad al código.</p>
	<p>Nos vamos a concentrar en las áreas que suelen cambiar.</p>
	<p>Para saber cuales áreas cambian mas, hay que conocer bien las reglas de negocio.</p>
</section>
<section class="slide" id="decorator13">
	<h2>Patron decorator</h2>
	<p>Vimos que representar nuestro brebaje con condimento con herencia no andaba muy bien, teniamos una explosion de clases (primer intento), diseños rígidos , o agregabamos funcionaidad a la clase base (segundo intento) que no era apropiada para todas las subclases y traia problemas de mantenimiento al agregar algun condimento.</p>
	<p>Lo que vamos a hacer con el patrón decorator vamos a arrancar con el brebaje y decorarlo con condimentos en tiempo de ejecución.</p>
	<p>Ej: el cliente quiere Dark Roast con Mocha y Whip</p>
	<ol>
		<li>Tomamos el objeto DarkRoast</li>
		<li>Lo decoramos con el objeto Mocha</li>
		<li>Lo decoramos con el objeto Whip</li>
		<li>Llamamos al metodo cost() que se basa en delegacion para agregarle los costos de cada condimento</li>
	</ol>
</section>
<section class="slide" id="decorator14">
	<h2>Como decoramos?</h2>
	<ol>
		<li>Arrancamos instanciando el objeto DarkRoast que hereda de Beverage, que tiene un método cost() para calcular el costo de la bebida.
		<p>Recordemos que el problema nuestro era el calculo de costo de los adicionales, que en una implementacion se hacía una clase para cada una de las opciones que se puedieran presentar y en la otra la supeclase era la que calculaba el costo los adicionales y luego la subclase el valor del producto específico.</p>
		<img src="DarkRoast.png"/>
		</li>
	</ol>
</section>
<section class="slide" id="decorator15">
	<h2>Como decoramos?</h2>
	<ol start=2>
		<li>Si queremos agregarle un adicional creamos el objeto del adicional y lo ponemos alrededor de él. Mocha (el de afuera) va a tener una relación de asociación con DarkRoast).<BR/>
		El objeto mocha es el decorador, tiene el mismo tipo del objeto que está decorando, en este caso brebaje.<BR/>
		Entonces mocha tiene un método costo también y usando el polimorfismo podemos tratar a cualquier objeto envuelto en mocha como un brebaje (Mocha es un subtipo de Beverage).
		<img src="Mocha(DarkRoast).png"/>
		</li>
	</ol>
</section>
<section class="slide" id="decorator16">
	<h2>Como decoramos?</h2>
	<ol start=3>
		<li>Si le queremos agregar Whip, creamos un objeto whip decorator y envolvemos con este a mocha.<BR/>
			Whip es un decorador asi que tambien tiene el mismo tipo que DarkRoast e implementa cost().<BR/>
			Un objeto DarkRoast envuelto en Mocha y Whip sigue siendo un brevaje y puede hacer todo lo que hacíamos con DarkRost incluyendo calcular cost()
		<img src="Whip(Mocha(DarkRoast)).png"/>
		</li>
	</ol>
</section>
<section class="slide" id="decorator17">
	<h2>Como decoramos?</h2>
	<ol start=4>
		<li>Ahora es tiempo de calcular el costo para un cliente, hacemos esto llamando cost() en el decorador más externo, Whip en este caso y este va a delegar el cálculo al objeto que decora.<BR/>
		Una ves que el de adentro le devuelve el costo le adiciona el costo suyo del condimiento Whip.
		<img src="Whip(Mocha(DarkRoast)).Cost().png"/>
		</li>
	</ol>
</section>
<section class="slide" id="decorator18">
	<h2>Resumiendo</h2>
	<ul>
		<li>Los decoradores tienen el mismo tipo del objeto que decoran, esto quiere decir que tienen una variable de instancia para lo que decoran</li>
		<li>Se puede usar mas de un decorador para envolver a un objeto.</li>
		<li>Dado que el decorador tiene el mismo supertipo del objeto que decora, podemos pasar sobre un objeto decorado en lugar del objeto original (envuelto).</li>
		<li>El decorador agrega su propio comportamiento o antes o después de delegar al objeto que decora para hacer el resto del trabajo.</li>
		<li>Los objetos pueden ser decorados en cualquier momento, podemos decorar objetos en tiempo de ejecución con la cantidad de decoradores que queramos.</li>
	</ul>
</section>
<section class="slide" id="decorator23">
	<h2>Implementación</h2>
	<h3>Decoramos nuestros Brebajes</h3>
	<img src="coffeStoresClassDiagram.png"/>
</section>

<section class="slide" id="decorator24">
	<h2>Implementación</h2>
	<p>Beverage es el <strong>Component</strong></p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
	public abstract class Beverage {
		String description = "Unknown Beverage";
	  
		public String getDescription() {
			return description;
		}
		public abstract double cost();
	}
	</script>
	<p>CondimentDecorator es la interface <strong>Decorator</strong></p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
	public abstract class CondimentDecorator extends Beverage {
		Beverage beverage;
		public CondimentDecorator(Beverage beverage){
			this.beverage = beverage;
		}
		public String getDescription(){
			return beverage.getDescription();
		}
	}
	</script>
</section>
<section class="slide" id="decorator25">
	<h2>Implementación</h2>
	<p>Ya tenemos las clases base, codeamos unos brebajes</p>
	<p>Los brebajes son los <strong>ConcreteComponent</strong></p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class Espresso extends Beverage {
			public Espresso() {
				description = "Espresso";
			}
			public double cost() {
				return 1.99;
			}
		}
	</script>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
	public class HouseBlend extends Beverage {
		public HouseBlend() {
			description = "House Blend Coffee";
		}
		public double cost() {
			return .89;
		}
	}
	</script>
</section>
<section class="slide" id="decorator26">
	<h2>Implementación</h2>
	<p>Y los condimentos que son los <strong>ConcreteDecorator</strong></p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class Mocha extends CondimentDecorator {
		 
			public Mocha(Beverage beverage) {
				super(beverage);
			}
		 
			public String getDescription() {
				return beverage.getDescription() + ", Mocha";
			}
		 
			public double cost() {
				return .20 + beverage.cost();
			}
		}
	</script>
	<ul>
		<li>Los Condimentos heredan de CondimentDecorator, que a su vez hereda de Beverage, uno lo obliga a implementar cost() y el otro getDescription()</li>
		<li>Tiene una instancia del Beverage que se está envolviendo</li>
		<li>En el constructor recibe el Beverage que esta decorando y guarda la referencia</li>
		<li>En cost(), pimero delega el calculo de costo al objeto que esta decorando, y luego se calcula el costo de agregarle el condimento al resultado</li>
		<li>En getDescription(), se va armando un string con los condimentos que le agregamos (decorando) el brebaje.</li>
	</ul>
</section>
<section class="slide" id="decorator27">
	<h2>Implementación</h2>
	<p>Finalmente el main</p>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
	public class StarbuzzCoffee {
	 
		public static void main(String args[]) {
			Beverage beverage = new Espresso();
			System.out.println(beverage.getDescription() + " $" + beverage.cost());
	 
			Beverage beverage2 = new DarkRoast();
			beverage2 = new Mocha(beverage2);
			beverage2 = new Mocha(beverage2);
			beverage2 = new Whip(beverage2);
			System.out.println(beverage2.getDescription() + " $" + beverage2.cost());
	 
			Beverage beverage3 = new HouseBlend();
			beverage3 = new Soy(beverage3);
			beverage3 = new Mocha(beverage3);
			beverage3 = new Whip(beverage3);
			System.out.println(beverage3.getDescription() + " $" + beverage3.cost());
		}
	}
	</script>
	<p>El resultado por consola</p>
	<script type="syntaxhighlighter" class="brush: plain; toolbar: false;">
		Espresso $1.99
		Dark Roast Coffee, Mocha, Mocha, Whip $1.49
		House Blend Coffee, Soy, Mocha, Whip $1.34
	</script>
</section>
<section class="slide" id="decorator19">
	<h2>Patrón Decorator</h2>
	<p>El patrón decorador agrega responsabilidades adicionales a un objeto dinámicamente.</BR>
		Provee una alternativa flexible a la herencia para extender funcionalidad.</p>
	<p>También es conocido como wrapper</p>	
	<ul>
		<li>Clasificación: Se clasifica como patrón Estructural en cuanto a propósito y de objetos en cuanto a ámbito porque utiliza la composición para cambiar el comportamiento en tiempo de ejecución.</li>
		<li>Motivación: A veces se quiere añadir funcionalidad a un objeto concreto, no a una clase entera</li>
		<li>Aplicabilidad:</li>
		<ul>
			<li>Para añadir responsabilidades a objetos concretos de manera dinámica y transparente, esto es, sin afectar a otros objetos</li>
			<li>Para responsabilidades que se pueden añadir y quitar</li>
			<li>Cuando la herencia sea impracticable, porque implique crear múltiples subclases para todas las combinaciones posibles</li>
			<li>Hay una necesidad de extender la funcionalidad de una clase, pero no hay razones para extenderlo a través de la herencia.</li>
			<li>Existe la necesidad de extender dinámicamente la funcionalidad de un objeto y quizás quitar la funcionalidad extendida.</li>
		</ul>
	</ul>
</section>
<section class="slide" id="decorator20">
	<h2>Patrón Decorator</h2>
	<ul>
		<li>Consecuencias:</li>
		<ul>
			<li>Es más flexible que la herencia estática. </li>
			<ul>
				<li>Las responsabilidades se añaden y eliminan dinámicamente</li>
				<li>Facilita definir una propiedad varias veces</li>
			</ul>	
			<li>Evita que las clases más altas en la jerarquía estén demasiado cargadas de funcionalidad y sean complejas</li>
			<ul>
				<li>No hay precio que pagar por propiedades que no se usan</li>
				<li>Facilita la definición de nuevos decoradores</li>
			</ul>	
			<li>Un decorador y el componente al que se refiere no son idénticos (osea tienen distinto identificador, cada uno tiene su estado propio)</li>
			<li>Provoca la creación de muchos objetos pequeños parecidos y encadenados, complicando la depuración</li>
		</ul>	
	</ul>
</section>
<section class="slide" id="decorator21">
	<h2>Patrón Decorator</h2>
	<ul>	
		<li>Participantes:</li>
		<ul>
			<li>Component: define la interfaz de los objetos a los que se puede añadir responsabilidades de manera dinámica</li>
			<li>ConcreteComponent: define un objeto al que añadir responsabilidades de manera dinámica</li>
			<li>Decorator: mantiene una referencia al objeto componente y define una interfaz conforme a la del componente, osea implementan la misma interface o clase abstracta que el componente que se va a decorar.</li>
			<li>ConcreteDecorator: añade responsabilidades al componente al que referencia.<BR/>
			El decorador concreto tiene una variable de instancia para lo que decora (el componente que el decorador envuelve)</li>
		</ul>	
	</ul>
</section>
<section class="slide" id="decorator22">
	<h2>Patrón Decorator</h2>
	<ul>	
		<li>Estructura:</li>
		<img src="decoratorClassDiagram.png"/>
	</ul>
</section>
<section class="slide" id="decorator28">
	<h2>Observaciones</h2>
	<p>Lo importante es que los decoradores tienen el mismo tipo que el objeto que van a decorar. Entonces vamos a usar herencia para lograr que coincidan los tipos pero no la usaremos para adquirir un comportamiento.</p>
	<p>Se ve el echo que necesitan la misma interface que los componentes que envuelven, porque tienen que ponerse en el lugar del componente.</p>
	<p>Cuando componemos un decorador con un componente (relación de composición entre component y decorator), le estamos agregando nuevo comportamiento, pero el comportamiento que le agregamos no es en base a herencia de una superclase sino de la composición.</p>
	<p>Cuando un breabaje (ConcreteComponent) hereda de la clase abstracta Beverage (Componet) es para tener el tipo correcto no para heredar comportamiento. <BR/>
	El comportamiento viene de la composición de decoradores con la clase base component así como de otros decoradores, lo que da gran flexibilidad, ademas de dejarnos dar comportamiento en tiempo de ejecución; en contraste con la herencia que dar comportamiento en tiempo de compilación, ademas de no tener que cambiar el código para hacer el cambio de comportamiento.</p>
</section>

<section class="slide" id="decorator29">
	<h2>Java I/O</h2>
	<p>La cantidad de clases que tiene la API de java es una locura. Pero ahora que sabemos Observer, las clase I/O van a tener mas sentido ya que java.io esta basado en decorator.</p>
	<p>Acá se ve un grupo de objetos que usan la decoración para agregar funcionalidad</p>
	<img src="javaio.png"/>
</section>
<section class="slide" id="decorator30">
	<h2>Java I/O</h2>
	<ul>
		<li>FileInputStream es el componente que esta siendo decorado. FileInputStream, StringBufferInputStream, ByteArrayInputStream y algunos otros son los componentes que nos provee la librería I/O de java, y estos nos dan el componente base para leer bytes</li>
		<li>BufferInputStream es un decorador concreto. Este agrega comportamientos en 2 aspectos:</li>
		<ul>
			<li>Guardar en un buffer la entrada para mejorar la performance</li>
			<li>Agrega a la interface un método nuevo readLine() para leer entrada de caracteres linea a linea</li>
		</ul>
		<li>LineNumberInputStream es un decorados concreto que agrega la capacidad de contar las lineas mientras va leyendo</li>
	</ul>
	<p><strong>BufferInputStream y LineNumberInputStream ambos extienden FilterInputStream que hace de AbstractDecorator</strong></p>
</section>
<section class="slide" id="decorator31">
	<h2>Java I/O</h2>
	<h3>Diagrama de clases java.io</h3>
	<img src="javaioClassDiagram.png"/> 
	<ul>
		<li>InputStream es AbstractComponent</li>
		<li>FilterInputStream es AbstractDecorator</li>
		<li>FilterInputStream es AbstractDecorator</li>
		<li>
			<p>Los Concrete de InputStream, son los que se van a decorar</p>
			<ul>
				<li>FileInputStream, StringBufferInputStream, ByteArrayInputStream</li>
			</ul>
		</li>
				<li>
			<p>Los ConcreteDecorators</p>
			<ul>
				<li>PushBackInputStream, BufferedInputStream, DataInputStream, LineNumberInputStream</li>
			</ul>
		</li>
	</ul>	
</section>
<section class="slide" id="decorator32">
	<h2>Java I/O</h2>
	<h3>Ejemplo de java I/O</h3>
	<script type="syntaxhighlighter" class="brush: java; toolbar: false;">
		public class JavaioReader {
			public static void main(String[] args) {
				try{
					FileInputStream fstream = new FileInputStream("archivo.txt");
					DataInputStream in = new DataInputStream(fstream);
					BufferedReader br = new BufferedReader(new InputStreamReader(in));
					String strLine;
					while ((strLine = br.readLine()) != null){
						System.out.println (strLine);
					}
					in.close();
				  }
				catch (Exception e){
					System.err.println("Error: " + e.getMessage());
				}
			}
		}
	</script>
	<p>Visto esto estamos en posicion de manejar la API java.io y tomar un InputStream y decorarlo. Pasa lo mismo con OutputStream o </p>
	<p>Los problemas que trae el uso de Decorator es la gran cantidad de pequeñas clases que se generan para dar la funcionalidad.</p>

</section>
<section class="slide" id="decorator88">
	<h2>Referencias</h2>
	<p><strong>Head First Design Patterns</strong></p>
</section>

<!----------------------------------------------------------------------------------------------->
<!-- deck.navigation snippet -->
<a href="#" class="deck-prev-link" title="Previous">&#8592;</a>
<a href="#" class="deck-next-link" title="Next">&#8594;</a>

<!-- deck.status snippet -->
<p class="deck-status">
	<span class="deck-status-current"></span>
	/
	<span class="deck-status-total"></span>
</p>

<!-- deck.goto snippet -->
<form action="." method="get" class="goto-form">
	<label for="goto-slide">Go to slide:</label>
	<input type="text" name="slidenum" id="goto-slide" list="goto-datalist">
	<datalist id="goto-datalist"></datalist>
	<input type="submit" value="Go">
</form>

<!-- deck.hash snippet -->
<a href="." title="Permalink to this slide" class="deck-permalink">#</a>


<!-- Grab CDN jQuery, with a protocol relative URL; fall back to local if offline -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.7.2/jquery.min.js"></script>
<script>window.jQuery || document.write('<script src="../jquery-1.7.2.min.js"><\/script>')</script>

<!-- Deck Core and extensions -->
<script src="../core/deck.core.js"></script>
<script src="../extensions/hash/deck.hash.js"></script>
<script src="../extensions/menu/deck.menu.js"></script>
<script src="../extensions/goto/deck.goto.js"></script>
<script src="../extensions/status/deck.status.js"></script>
<script src="../extensions/navigation/deck.navigation.js"></script>
<script src="../extensions/scale/deck.scale.js"></script>

<!-- Initialize the deck -->
<script>
$(function() {
	$.deck('.slide');
});
</script>

</body>



</html>
